<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>管道运算符</title>
</head>
<body>
    <h1>管道运算符</h1>
    <h2>用来方便地将一个函数的输出传给另一个函数</h2>

    <script>
        // 目前的写法
        const result = h(g(f(x)));

        // 管道运算符提案的写法
        /*
        const result = x |> f |> g |> h;
        */

        // 实际应用示例
        // 1. 数据处理流程
        function double(n) { return n * 2; }
        function addOne(n) { return n + 1; }
        function square(n) { return n * n; }

        // 传统写法
        const processNumber = x => square(addOne(double(x)));
        console.log(processNumber(2)); // 25

        // 模拟管道运算符
        const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
        const processNumberPiped = pipe(double, addOne, square);
        console.log(processNumberPiped(2)); // 25

        // 2. 字符串处理
        const trim = s => s.trim();
        const capitalize = s => s.charAt(0).toUpperCase() + s.slice(1);
        const exclaim = s => s + '!';

        const processString = pipe(trim, capitalize, exclaim);
        console.log(processString('  hello  ')); // "Hello!"

        // 3. 数组处理
        const numbers = [1, 2, 3, 4, 5];
        const processArray = pipe(
            arr => arr.filter(n => n % 2 === 0),
            arr => arr.map(n => n * 2),
            arr => arr.reduce((sum, n) => sum + n, 0)
        );

        console.log(processArray(numbers)); // 12

        // 4. 异步管道
        const asyncPipe = (...fns) => x => 
            fns.reduce(async (v, f) => f(await v), x);

        async function fetchUser(id) {
            return { id, name: 'User' + id };
        }

        async function fetchPosts(user) {
            return { user, posts: ['post1', 'post2'] };
        }

        async function formatData(data) {
            return {
                userName: data.user.name,
                postCount: data.posts.length
            };
        }

        const processUserData = asyncPipe(
            fetchUser,
            fetchPosts,
            formatData
        );

        processUserData(1).then(console.log);
    </script>
</body>
</html> 